﻿using System;
using System.Collections.Generic;
using System.Linq;

#if SILVERLIGHT
using System.Windows;
#endif

namespace KKSGameLibrary.Logic
{
    public class RegionInMap
    {
        public override string ToString()
        {
            return string.Format(
            "Region:{0}\t{1}\nCards:{2}\tEdges:{3}\nScore:{4}\tOwners{5}\nTTime:{6}\nCPlayer:{7}",
            RegionId,
            RegionCardType,
            Cards.Count,
            OpenEdges.Count,
            Score,
            OwnerPuppets.Count,
            TakeOwnerTime,
            Creator.ID);
        }

        internal RegionInMap()
        {
            Cards = new List<CardInMap>();
            OpenEdges = new List<OpenEdge>();
            OwnerPuppets = new List<PlayerPuppet>();
        }
        public CardType RegionCardType { set; get; }
        public List<CardInMap> Cards { private set; get; }
        public List<OpenEdge> OpenEdges { private set; get; }
        public string RegionId { set; get; }
        public bool IsComplete { set; get; }
        public int Score { set; get; }
        public List<PlayerPuppet> OwnerPuppets {private set; get; }
        public DateTime TakeOwnerTime { set; get; }
        public GamePlayer Creator { set; get; }

        internal void PlayerTakeOwner(PlayerPuppet puppet)
        {
            if (this.OwnerPuppets.Count > 0 && puppet.Player.PuppetRemain < 1)
                throw new Exception("canot own this region");
            else
            {
                TakeOwnerTime = DateTime.Now;
                this.OwnerPuppets.Add(puppet);
                puppet.Player.OwnedRegionCount++;
                puppet.Player.PuppetRemain--;
            }
        }

        internal RegionUpdateResult UpdateState()
        {
            // church complete
            if (RegionCardType == CardType.Church
                && Cards.Count == 9)
            {
                IsComplete = true;
                Score = 18;
            }

            // castle
            if (RegionCardType == CardType.Castle &&
                OpenEdges.Count == 0)
            {
                IsComplete = true;
                Score = Cards.Count * 2;
            }

            if (RegionCardType == CardType.Road &&
                OpenEdges.Count == 0)
            {
                IsComplete = true;
                Score = Cards.Count;
            }

            var result = new RegionUpdateResult();

            if (IsComplete)
            {
                result.IsCompleted = true;

                if (OwnerPuppets.Count == 0)
                {
                    Creator.Score += this.Score;
                    var newcreatorpuppet = new PlayerPuppet
                    {
                        Player = Creator
                    };
                    result.ScoreList[newcreatorpuppet] = this.Score;
                }
                else
                {
                    int scoreperpalyer = this.Score / this.OwnerPuppets.Count;
                    foreach (var owner in this.OwnerPuppets)
                    {
                        owner.Player.Score += scoreperpalyer;
                        result.ScoreList[owner] = scoreperpalyer;
                    }
                }
                
#if SILVERLIGHT
                //MessageBox.Show("Complete!\nScore: " + Score);
#endif
            }
            return result;
        }

        internal RegionMergeResult MergeRegion(RegionInMap regionInMap)
        {
            if (regionInMap.RegionCardType != this.RegionCardType ||
                !(regionInMap.RegionCardType == CardType.Road ||
                regionInMap.RegionCardType == CardType.Castle))
                throw new Exception("cannot merge these two card");

            var result = new RegionMergeResult();
            result.IsMerged = true;

            // merge cards
            foreach (var card in regionInMap.Cards)
            {
                if (!this.Cards.Contains(card))
                    this.Cards.Add(card);
            }

            // merge edges
            regionInMap.OpenEdges.ForEach(
                e => this.OpenEdges.Add(e));

            // merage owner
            if (regionInMap.OwnerPuppets.Count > 0)
            {
                if (this.RegionCardType == CardType.Castle)
                    foreach(var owner in regionInMap.OwnerPuppets)
                    {
                        // duplicated owner
                        var existedowner = this.OwnerPuppets.FirstOrDefault(pp => pp.Player == owner.Player);
                        if (existedowner != null)
                        {
                            result.RemovedPuppet = owner;
                            existedowner.Player.PuppetRemain++;
                        }
                        else
                            this.OwnerPuppets.Add(owner);
                    }
                else
                    if (this.RegionCardType == CardType.Road)
                    {
                        if (this.OwnerPuppets.Count == 0 && regionInMap.OwnerPuppets.Count > 0)
                            this.OwnerPuppets.Add(regionInMap.OwnerPuppets[0]);
                        else if (this.OwnerPuppets.Count > 0 && regionInMap.OwnerPuppets.Count > 0)
                        {
                            if (this.TakeOwnerTime > regionInMap.TakeOwnerTime)
                            {
                                this.OwnerPuppets[0].Player.OwnedRegionCount--;
                                this.OwnerPuppets[0].Player.PuppetRemain++;

                                result.RemovedPuppet = this.OwnerPuppets[0];
                                this.OwnerPuppets.Clear();
                                this.OwnerPuppets.Add(regionInMap.OwnerPuppets[0]);
                            }
                            else
                            {
                                result.RemovedPuppet = regionInMap.OwnerPuppets[0];
                                regionInMap.OwnerPuppets[0].Player.OwnedRegionCount--;
                                regionInMap.OwnerPuppets[0].Player.PuppetRemain++;
                            }
                        }                      
                    }
            }
            return result;
        }

    }
}
